home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
t3_1
/
doc.lha
/
documentation
/
manual
/
stream.mss
< prev
next >
Wrap
Text File
|
1987-06-30
|
19KB
|
507 lines
@part[Streams, Root "TMAN.MSS"] @Comment{-*-System:TMAN-*-}
@chap[Streams]
@dc[ Some general comments are in order: ]
A @i[stream] is any object which handles stream operations. In general,
streams are objects which contain pointers into sequences of objects.
The stream operations provide for obtaining objects from such a
sequence, advancing a stream's pointer, performing side effects
on the sequence itself, and so forth.
@dc[ Opening and closing streams. ]
@dc[ Input and output streams. ]
@dc[ Comparison with streams in the AI sense - those don't have state; they
are instead like infinite (lazy) lists. ]
@tau[] programs communicate with the external world via @ix[streams].
Streams may access file systems or terminals. They may also be used
to implement filters and buffers of various sorts.
Streams are manipulated using generic operations. Most of the
procedures described below are generic operations, and their
descriptions either specify the behavior of their default methods
or of the methods for system-supplied streams. Users may create
streams to their own specifications using @tc[OBJECT]-expressions.
As long as a user stream supports
@tc[READ-CHAR] and @tc[UNREAD-CHAR] (for input streams) or
@tc[WRITE-CHAR] (for output streams), most of the other I/O operations
will work with them.
@section[General]
@info[NOTES="Type predicate operation"]
@desc[(STREAM? @i[object]) @yl[] @i[boolean]]
Returns true if @i[object] is a stream.
@EndDesc[STREAM?]
@info[NOTES="Type predicate operation"]
@desc[(INPUT-STREAM? @i[object]) @yl[] @i[boolean]]
Returns true if @i[object] is an input stream.
@EndDesc[INPUT-STREAM?]
@info[NOTES="Type predicate operation"]
@desc[(OUTPUT-STREAM? @i[object]) @yl[] @i[boolean]]
Returns true if @i[object] is an output stream.
@EndDesc[OUTPUT-STREAM?]
@info[NOTES="Type predicate operation"]
@desc[(INTERACTIVE-STREAM? @i[object]) @yl[] @i[boolean]]
Returns true if @i[object] is an @iix[interactive] stream.
An interactive stream is any input stream which is likely to have
a human being at the other end, for example, a terminal input stream.
@EndDesc[INTERACTIVE-STREAM?]
@info[NOTES="Type predicate"]
@desc[(EOF? @i[object]) @yl[] @i[boolean]]
Returns true if @i[object] is the end-of-file token.
(@qu"End-of-stream" would be a more appropriate term.)
@EndDesc[EOF?]
@desc[*EOF* @yl[] @i[end-of-file]]
This global variable holds the end-of-file token.
@EndDesc[*EOF*]
@info[Notes "Special form"]
@desc[@el[](WITH-OPEN-STREAMS @i[specs] . @i[body]) @yl[] @i[object]]
@tc[WITH-OPEN-STREAMS] has the same syntax as @tc[LET],
and similar semantics.
Each @i[spec] should be of the form @wt[(@i[variable stream])].
Each @i[stream] expression
is evaluated, and should evaluate to a stream;
for example, @i[stream] would typically be an expression
involving @tc[OPEN] or @tc[MAYBE-OPEN].
The @i[body], an implicit block, is evaluated in a lexical context in which
each @i[variable] is bound to the value of the corresponding
@i[stream] expression.
The streams are closed,
and the value of @i[body] is returned.
@tc[WITH-OPEN-STREAMS] is the preferred way to use stream creation
operations such as @tc[OPEN]. It ensures that the
streams will be closed, even if there is a non-local exit (a
@tc[(RESET)] or any other kind of
throw) out of @i[body] or any of the @i[stream] expressions.
(See @tc[UNWIND-PROTECT], page @pageref[UNWIND-PROTECT].)
For an example, see @tc[OPEN], page @pageref[OPEN].
@EndDesc[WITH-OPEN-STREAMS]
@info[NOTES="Operation"]
@desc[(CLOSE @i[stream]) @yl[] @i[undefined]]
Closes @i[stream]; indicates that no more input or output is intended,
and that any resources associated with it may be freed.
@EndDesc[CLOSE]
@desc[(STRING->INPUT-STREAM @i[string]) @yl[] @i[stream]]
Returns an input stream which yields successive characters of @i[string]
on successive @tc[READ-CHAR]'s.
@EndDesc[STRING->INPUT-STREAM]
@info[notes "Special form"]
@desc[(WITH-INPUT-FROM-STRING (@i[variable string]) . @i[body]) @yl[] @~
@i[value-of-body]]
Opens an input stream to @i[string], binds @i[variable] to that
stream, and evaluates @i[body], returning whatever @i[body] returns.
@ProgramExample[
(WITH-INPUT-FROM-STRING (@i[variable string]) . @i[body])
@ce[]
(WITH-OPEN-STREAMS ((@i[variable] (STRING->INPUT-STREAM @i[string])))
. @i[body])
]
@EndDesc[WITH-INPUT-FROM-STRING]
@info[NOTES="Special form"]
@desc[(WITH-OUTPUT-TO-STRING @i[var . body]) @yl[] @i[string]]
Binds @i[var] to an output stream. The @i[body] (an implicit block) is
evaluated, and any characters written to the stream are
collected in a string, which is returned as the value of the
@tc[WITH-OUTPUT-TO-STRING] form.
@begin[ProgramExample]
(WITH-OUTPUT-TO-STRING FOO (WRITE FOO '(A B))) @ev[] "(A B)"
@end[ProgramExample]
@EndDesc[WITH-OUTPUT-TO-STRING]
@section[Stream switches]
@info[Notes "Settable"]
@desc[(TERMINAL-INPUT) @yl[] @i[stream]]
Accesses the default stream for input from the terminal.
Note that an end-of-file condition on the terminal input stream (see
page @pageref[end-of-file]) will cause the end-of-file token to be
returned as the value of the next input operation on that stream,
but will not cause the stream to become closed. This is an exception
to the normal rule that no input is available from a stream following
an end-of-file condition on it.
@EndDesc[TERMINAL-INPUT]
@info[Notes "Settable"]
@desc[(TERMINAL-OUTPUT) @yl[] @i[stream]]
Accesses the default stream for output to the terminal.
@EndDesc[TERMINAL-OUTPUT]
@info[Notes "Settable"]
@desc[@el[](STANDARD-INPUT) @yl[] @i[stream]]
Accesses the default standard input stream.
Initially, this is the same as the value of @tc[(TERMINAL-INPUT)].
The intent is that a program could do all its input from
the standard input stream.
By default, input would come from the terminal. But some procedure could
set the standard input stream to be a file, for example, and then
call the program, which would automatically read from the file.
This same idea is used for all the following predefined streams.
@EndDesc[STANDARD-INPUT]
@info[Notes "Settable"]
@desc[@el[](STANDARD-OUTPUT) @yl[] @i[stream]]
Accesses the default standard output stream.
Initially, this is the same as the value of @tc[(TERMINAL-OUTPUT)].
@EndDesc[STANDARD-OUTPUT]
@info[Notes "Settable"]
@desc[(ERROR-OUTPUT) @yl[] @i[stream]]
Initially, yields the same value as @tc[(TERMINAL-OUTPUT)].
@EndDesc[ERROR-OUTPUT]
@info[Notes "Settable"]
@desc[(DEBUG-OUTPUT) @yl[] @i[stream]]
Initially, yields the same value as @tc[(TERMINAL-OUTPUT)].
@EndDesc[DEBUG-OUTPUT]
@section[Input]
@AnEquivE[Tfn="READ-CHAR",Efn="TYI"]
@AnEquivE[Tfn="READ-CHAR",Efn="READCH"]
@info[NOTES="Operation"]
@descN[
F1="@el[](READ-CHAR @i[stream]) @yl[] @i[character] @r[or] @i[end-of-file]",
FN1="READ-CHAR",
F2="@el[](READC @i[stream]) @yl[] @i[character] @r[or] @i[end-of-file]",
FN2="READC"
]
Reads a single character from @i[stream], advances the stream pointer,
and returns the character read. If no character is available, then
the end-of-file token is returned.
@EndDescN[]
@info[NOTES="Operation"]
@descN[
F1 = "(UNREAD-CHAR @i[stream]) @yl[] @i[undefined]",
FN1 = "UNREAD-CHAR",
F2 = "(UNREADC @i[stream]) @yl[] @i[undefined]",
FN2 = "UNREADC"
]
Backs up @i[stream]'s pointer into its corresponding sequence of
characters by one character. This causes the
next @tc[READ-CHAR] from @i[stream] to return @i[character] instead of
actually reading another character. @i[Character] is returned.
@tc[UNREAD-CHAR] is convenient for implementing one-character-lookahead
scanners. Only the previous character @tc[READ-CHAR]'ed from @i[stream]
may be put back, and it may be put back only once.
@dc{ Explain why one needs to supply the character at all. }
@EndDescN[]
@AnEquivE[Tfn="PEEK-CHAR",Efn="TYIPEEK"]
@info[NOTES="Operation"]
@descN[
F1="(PEEK-CHAR @i[stream]) @yl[] @i[character] @r[or] @i[end-of-file]",
FN1="PEEK-CHAR",
F2="(PEEKC @i[stream]) @yl[] @i[character] @r[or] @i[end-of-file]",
FN2="PEEKC"
]
Returns the next character available on @i[stream] without
advancing the stream's pointer.
If no character is there then the end-of-file token is returned.
@begin[ProgramExample]
(PEEK-CHAR @i[stream]) @ce[]
(BLOCK0 (READ-CHAR @i[stream]) (UNREAD-CHAR @i[stream]))
@end[ProgramExample]
@EndDescN[]
@AnEquivE[Tfn="READ-LINE",Efn="READLINE"]
@info[NOTES="Operation"]
@desc[(READ-LINE @i[stream]) @yl[] @i[string] @r[or] @i[end-of-file]]
Reads a line of input from @i[stream] and returns it as a string.
If no input is available then the end-of-file token is returned.
@EndDesc[READ-LINE]
@AnEquivE[Tfn="READ",Efn="READ"]
@info[NOTES="Operation"]
@desc[@el[](READ @i[stream]) @yl[] @i[object] @r[or] @i[end-of-file]]
Reads an object from @i[stream]. The default method simply calls
@tc[READ-OBJECT], passing it the stream and
the stream's current associated read table. See @tc[READ-OBJECT],
page @pageref[READ-OBJECT], and @tc[STREAM-READ-TABLE], page
@pageref[STREAM-READ-TABLE].
@EndDesc[READ]
@desc[(READ-REFUSING-EOF @i[stream]) @yl[] @i[object]]
This is like @tc[READ] but should be used in cases where an end-of-file
is not appropriate or is not handled, such as within
the definition of a read macro.
@EndDesc[READ-REFUSING-EOF]
@desc[(READ-OBJECTS-FROM-STRING @i[string]) @yl[] @i[list]]
Returns a list of all the objects that could be read from the string.
@begin[ProgramExample]
(READ-OBJECTS-FROM-STRING "A B C") @ev[] (A B C)
(READ-OBJECTS-FROM-STRING " 015 ( Foo ) ") @ev[] (15 (FOO))
(READ-OBJECTS-FROM-STRING "") @ev[] ()
@end[ProgramExample]
@EndDesc[READ-OBJECTS-FROM-STRING]
@info[NOTES="Operation"]
@desc[(CLEAR-INPUT @i[stream]) @yl[] @i[undefined]]
Discards any buffered input for @i[stream].
The precise action of this operation is implementation-dependent.
@EndDesc[CLEAR-INPUT]
@section[Output]
@info[EQUIV="PRIN1",NOTES="Operation"]
@desc[@el[](PRINT @i[object stream]) @yl[] @i[undefined]]
Prints @i[object] on @i[stream] according to the current read-table.
This is an operation, so objects may decide how they would like
to print.
@EndDesc[PRINT]
@AnEquivE[Tfn="WRITE",Efn="PRIN1"]
@info[NOTES="Operation"]
@desc[(WRITE @i[stream object]) @yl[] @i[undefined]]
Prints the @i[object] on @i[stream]. This is like @tc[PRINT] with the
argument order reversed.
This is an operation, so particular streams may decide how they want
to write objects to themselves.
@EndDesc[WRITE]
@AnEquivE[Tfn="WRITEC",Efn="TYO"]
@info[NOTES="Operation"]
@descN[
F1="@el[](WRITE-CHAR @i[stream character]) @yl[] @i[undefined]",
FN1="WRITE-CHAR",
F2="@el[](WRITEC @i[stream character]) @yl[] @i[undefined]",
FN2="WRITEC"
]
Writes a single @i[character] to @i[stream].
@EndDescN[]
@AnEquivE[Tfn="WRITES",Efn="PRINC"]
@info[NOTES="Operation"]
@descN[
F1="@el[](WRITE-STRING @i[stream string]) @yl[] @i[undefined]",
FN1="WRITE-STRING",
F2="@el[](WRITES @i[stream string]) @yl[] @i[undefined]",
FN2="WRITES"
]
Writes @i[string] to @i[stream].
@EndDescN[]
@info[NOTES="Operation"]
@desc[(WRITE-LINE @i[stream string]) @yl[] @i[undefined]]
Writes @i[string] to @i[stream] (like @tc[WRITE-STRING]),
then does a @tc[NEWLINE] operation.
@EndDesc[WRITE-LINE]
@desc[(WRITE-SPACES @i[stream count]) @yl[] @i[undefined]]
Writes @i[count] space characters to @i[stream].
@EndDesc[WRITE-SPACES]
@info[EQUIV="PRINC",NOTES="Operation"]
@desc[(DISPLAY @i[object stream]) @yl[] @i[undefined]]
Prints @i[object] on @i[stream], but omits any slashes, delimiters, etc., when
printing strings, symbols, and characters.
@EndDesc[DISPLAY]
@info[EQUIV="SPRINTER",NOTES="Operation"]
@desc[(PRETTY-PRINT @i[object stream]) @yl[] @i[undefined]]
Pretty-prints @i[object] on @i[stream].
@EndDesc[PRETTY-PRINT]
@info[NOTES="Operation",EQUIV="TERPRI"]
@desc[(NEWLINE @i[stream]) @yl[] @i[undefined]]
Begins a new line on the given output @i[stream].
@EndDesc[NEWLINE]
@info[NOTES="Operation",EQUIV="TERPRI"]
@desc[(FRESH-LINE @i[stream]) @yl[] @i[undefined]]
If not at the beginning of a line,
begins a new line on the given output @i[stream].
@EndDesc[FRESH-LINE]
@info[NOTES="Operation"]
@desc[(SPACE @i[stream]) @yl[] @i[undefined]]
Write whitespace to @i[stream]. Ordinarily this will simply write
a space character, but if the current output line has overflowed
a @qu"reasonable" right margin, this will do a @tc[NEWLINE].
@EndDesc[SPACE]
@info[NOTES="Operation"]
@desc[(FORCE-OUTPUT @i[stream]) @yl[] @i[undefined]]
Makes sure any buffered output to @i[stream] is forced out.
This is useful especially with terminal output streams.
The precise behavior of this operation is implementation-dependent.
@EndDesc[FORCE-OUTPUT]
@section[Formatted output]
@AnEquivE[Tfn="FORMAT",Efn="MSG"]
@desc[@el[](FORMAT @i[destination control-string] . @i[rest]) @yl[] @i[string] @r[or] @i[undefined]]
Performs formatted output.
Characters in the @i[control-string] other than tilde (@tilde[])
are simply written to @i[destination].
When a tilde is encountered, special action is taken
according to the character following the tilde.
@i[Destination] should be one of the following:
@begin[Itemize]
A stream. In this case, output is simply written to the stream.
The value returned by the call to @tc[FORMAT] is undefined.
The standard true value. (This is the value of the system variable @tc[T].)
This is equivalent to a stream argument of @tc[(STANDARD-OUTPUT)].
The value returned by the call to @tc[FORMAT] is undefined.
Null. In this case the output is collected in a string, as with
@tc[WITH-OUTPUT-TO-STRING]. This string is returned as the value of
the call to @tc[FORMAT].
@end[Itemize]
The @tc[FORMAT] control sequences are as follows.
(Case is irrelevant, so @tilde[]@tc[A] and @tilde[]@tc[a] behave identically.)
@begin[Display]
@tilde[]@tc[A] @tc[DISPLAY] the next format argument.
@tilde[]@tc[B] Print the next argument in binary.
@tilde[]@tc[D] Print the next argument in decimal (radix ten).
@tilde[]@tc[O] Print the next argument in @ix[octal] (radix eight).
@tilde[]@tc[P] Write the character @qu"@tc[s]" if the next argument,
which must be a number, is not equal to 1 (for plurals).
@tilde[]@tc[R] @tilde[]@i[n]@tc[R] prints the next argument in radix @i[n].
@tilde[]@tc[S] @tc[PRINT] the next format argument.
@tilde[]@tc[T] @tilde[]@i[n]@tc[T] tabs to column @i[n] (@tc[HPOS]).
@tilde[]@tc[X] Print the next argument in @ix[hexadecimal] (radix sixteen).
@tilde[]@tc[%] Go to a new output line (@tc[NEWLINE]).
@tilde[]@tc[&] Go to a fresh output line (@tc[FRESH-LINE]).
@tilde[]@tc[_] Print a space, or go to a fresh output line (@tc[SPACE]).
@tilde[]@tilde[] Write a tilde.
@end[Display]
A tilde followed by any whitespace character is ignored, along with all
following whitespace.
@begin[ProgramExample]
(FORMAT NIL "The ~s eats grass." 'ELAND) @ev[] "The ELAND eats grass."
(FORMAT NIL "The ~A eats grass." "kudu") @ev[] "The kudu eats grass."
(FORMAT NIL "~S had ~X goat~P." '(SANDY SMITH) 31 31)
@ev[] "(SANDY SMITH) had 1F goats."
@end[ProgramExample]
@dc{ Explain numeric prefix parameters. }
@dc{ Are there other features? }
@dc{ Say somewhere that newlines follow output, like in C, rather than
preceding output, as in Maclisp. }
@EndDesc[FORMAT]
@section[Miscellaneous]
@info[NOTES="Settable operation"]
@desc[(STREAM-READ-TABLE @i[stream]) @yl[] @i[read-table]]
Accesses the read table associated with @i[stream].
See section @ref[readtables].
@EndDesc[STREAM-READ-TABLE]
@info[NOTES="Settable operation"]
@desc[(LINE-LENGTH @i[stream]) @yl[] @i[integer]]
Returns the maximum width that lines read from @i[stream] are likely to take,
or that lines written to @i[stream] ought to take.
@BeginInset[Bug:]
In @Timp[] 2.7, the @tc[LINE-LENGTH] of system-supplied streams is
not settable.
@EndInset[]
@EndDesc[LINE-LENGTH]
@info[NOTES="Settable operation",EQUIV="CURSORPOS"]
@desc[(HPOS @i[stream]) @yl[] @i[integer]]
Accesses the current horizontal position (column number) of @i[stream].
The leftmost position on a line is column 0.
When assigned, as many spaces as necessary are written to bring the
horizontal position to the assigned value.
@EndDesc[HPOS]
@info[NOTES="Settable operation",EQUIV="CURSORPOS"]
@desc[(VPOS @i[stream]) @yl[] @i[integer]]
Accesses the current vertical position (line number) of @i[stream].
The uppermost vertical position is line 0.
@EndDesc[VPOS]
@info[notes "Special form"]
@desc[(WITH-OUTPUT-WIDTH-STREAM @i[variable] . @i[body]) @yl[] @i[integer]]
Binds @i[variable] to an output stream, and evaluates @i[body] in
the augmented lexical environment.
The characters sent to the output stream are not accumulated, but
merely counted, and the total is returned as the value of
@tc[WITH-OUTPUT-WIDTH-STREAM].
@EndDesc[WITH-OUTPUT-WIDTH-STREAM]
@info[EQUIV="FLATSIZE"]
@desc[(PRINTWIDTH @i[object]) @yl[] @i[integer]]
Returns the number of @tc[WRITEC]'s
which would be performed were @i[object] to be printed using @tc[PRINT].
@ProgramExample[
(PRINTWIDTH @i[object])
@ce[]
(WITH-OUTPUT-WIDTH-STREAM STREAM (PRINT @i[object] STREAM))
]
@EndDesc[PRINTWIDTH]
@info[EQUIV="FLATC"]
@desc[(DISPLAYWIDTH @i[object]) @yl[] @i[integer]]
Returns the number of @tc[WRITEC]'s
which would be performed were @i[object] to be printed using @tc[DISPLAY].
@PROGRAMEXAMPLE[
(DISPLAYWIDTH @i[object])
@ce[]
(WITH-OUTPUT-WIDTH-STREAM STREAM (DISPLAY @i[object] STREAM)
]
@EndDesc[DISPLAYWIDTH]
@desc[(MAKE-BROADCAST-STREAM . @i[output-streams]) @yl[] @i[stream]]
Returns a stream which will @qu"broadcast" all output operations to
all of the @i[output-streams]. For example, if the stream @i[s] is the
value of a call
@begin[ProgramExample]
(MAKE-BROADCAST-STREAM @i[q] @i[r])
@end[ProgramExample]
then any @tc[WRITEC] (@tc[WRITES], @tc[SPACE], etc.) operation
to @i[s] will result in @tc[WRITEC] operations on both
@i[q] and @i[r].
@enddesc[MAKE-BROADCAST-STREAM]
@section[Example]
Here is an example of a user-defined stream.
@tc[MAKE-PREFIXED-STREAM] returns a stream
which prefixes each line written to a given stream with a given string.
@begin[ProgramExample]
(DEFINE (MAKE-PREFIXED-STREAM STREAM PREFIX)
(JOIN (OBJECT NIL
((NEWLINE SELF) (NEWLINE STREAM) (WRITES STREAM PREFIX))
((PRINT SELF OSTREAM)
(FORMAT OSTREAM
"#{Prefixed-stream@tilde[]_@tilde[]S@tilde[]_@tilde[]S}"
STREAM
PREFIX)))
STREAM))
@end[ProgramExample]